# -*- coding: utf-8 -*-

# @File  : business.py
# @Author: Lomo
# @Site  : lomo.space
# @Date  : 2020-02-17
# @Desc  : 业务层相关方法抽取


import random
import datetime
import threading

from config.area import AREA_INFO
from config.config import HOST


class Business(object):

    __instance_lock = threading.Lock()

    def __init__(self, prefix='api', env_id='17', env='dev'):
        print('init ...')
        self.host = 'https://' + HOST['prefix'].get(prefix) + str(env_id) + HOST['host'].get(env)

    def __new__(cls, *args, **kwargs):
        print('__new__ ...')
        if not hasattr(Business, '_instance'):
            with Business.__instance_lock:
                if not hasattr(Business, '_instance'):
                    Business._instance = object.__new__(cls)
        return Business._instance

    @staticmethod
    def simple_chinese(length):
        """
        随机生成指定长度的简体中文
        :param length: int, 字符串长度
        :return: str, 字符串
        """
        arr = list()
        for i in range(length):
            first = random.randint(0xB0, 0xF7)
            last = random.randint(0xA1, 0xFE)
            str_ = '{0:x}{1:x}'.format(first, last)
            try:
                zh = bytes.fromhex(str_).decode('gb2312')
                arr.append(zh)
            except UnicodeDecodeError as e:
                print(e)
        return ''.join(arr)

    @staticmethod
    def mobile_number(env='dev'):
        """
        随机生成 11 位电话号码
        :param env: str, 环境类型(dev下, 支持 19 开头的号码)
        :return: str, mobile phone number
        """
        second_num = [3, 4, 5, 6, 7, 8, 9]
        second_num = second_num[random.randint(0, 6)] if env == 'dev' else second_num[random.randint(0, 5)]
        third_num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][random.randint(0, 9)]
        last = random.randint(9999999, 100000000)  # 后八位

        return "1{0}{1}{2}".format(second_num, third_num, last)

    @classmethod
    def __check_digit(cls, id_number):
        check_sum = 0
        for i in range(0, 17):
            check_sum += ((1 << (17 - i)) * 11) * int(id_number[i])
        check_digit_ = (12 - (check_sum % 11)) % 11
        return check_digit_ if check_digit_ < 10 else 'X'

    @classmethod
    def id_card(cls, sex=0):
        """
        随机生成 18 位身份证号码
        :param sex: int, 性别 0/1
        :return: str
        """
        # 6 位区域码
        id_number = str(random.choice(list(AREA_INFO.keys())))
        # 出生日期
        start = datetime.datetime.strptime('1960-01-01', '%Y-%m-%d')
        end = datetime.datetime.strptime('2099-12-31', '%Y-%m-%d')
        birth = datetime.datetime.strftime(start + datetime.timedelta(random.randint(0, (end - start).days + 1)),
                                           '%Y%m%d')
        id_number += str(birth)
        # 2 位顺序码
        id_number += str(random.randint(10, 99))
        # 1 位性别码
        id_number += str(random.randrange(sex, 10, step=2))
        # 1 位校验码
        return id_number + str(cls().__check_digit(id_number))
